package com.j.lemon.learn.tcp;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author lijunjun
 * @Date 2020-06-24 14:47
 * @Description
 */
public class TimeClientHandler extends ChannelInboundHandlerAdapter {
    /**
     * 因为 Netty 采用线程池，所以这里使用原子操作类来进行计数
     */
    private static AtomicInteger atomicInteger = new AtomicInteger();

    /**
     * 当客户端和服务端 TCP 链路建立成功之后，Netty 的 NIO 线程会调用 channelActive 方法
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        /**
         * 连续发送 50 条数据
         */
        for (int i = 0; i < 50; i++) {
            /**
             * 解决 TCP 粘包的策略之一就是：在包尾增加回车换行符进行分割
             * System.getProperty("line.separator");屏蔽了 Windows和Linux的区别
             * windows 系统上回车换行符 "\n",Linux 上是 "/n"
             */
            String reqMsg = "<85>charGate:optTime=20200611150731,sessionId=489508782-721519661620257,sessionIdPa=hXlBJXJRJ7mkGrvndvBqDFylB2nSb1WqzTtp2y1vqGH4cPXgTxR0!-1170965339!1410847889067,pracct=dingyi,slacct=foura,srcIP=192.168.62.113,srcMAC=00:24:E8:AE:28:B6,srcHost=PC-DING,dstIP=192.168.32.204,dstPort=22,dstName=db204,dstId=1791,dstHost=host204,oper=ls,operProtocol=SSH,operDir=/home/foura,result=0,despCmd=ls t,extJson=JTdCJTIyb3BlclJlc3AlMjIlM0ElMjJ0MSUyMHQyJTIyJTdE,errMsg=,workOrder=,workOrderType=,fromSys=UGATE"+i + "\n";
            System.out.println(reqMsg);
            byte[] reqMsgByte = reqMsg.getBytes("UTF-8");
            ByteBuf reqByteBuf = Unpooled.buffer(reqMsgByte.length);
            /**
             * writeBytes：将指定的源数组的数据传输到缓冲区
             * 调用 ChannelHandlerContext 的 writeAndFlush 方法将消息发送给服务器
             */
            reqByteBuf.writeBytes(reqMsgByte);
            /**
             * 每次发送的同时进行刷新
             */
            ctx.writeAndFlush(reqByteBuf);
        }
    }

    /**
     * 当服务端返回应答消息时，channelRead 方法被调用，从 Netty 的 ByteBuf 中读取并打印应答消息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        /**
         * 这个 msg 已经是解码成功的消息，所以不再需要像以前一样使用 ByteBuf 进行编码
         * 直接转为 string 字符串即可*/
        String body = (String) msg;
        System.out.println((atomicInteger.addAndGet(1)) + "---" + Thread.currentThread().getName() + ",Server return Message：" + body);
    }

    /**
     * 当发生异常时，打印异常 日志，释放客户端资源
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        /**释放资源*/
        ctx.close();
    }

}
